package cn.ffcs.base.dao;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cn.ffcs.base.model.BaseEntity;
import cn.ffcs.base.web.PageControl;
import cn.ffcs.system.dict.model.DictType;
import cn.ffcs.util.ext.Expression;

/**
 * DAO基础代码<br/> 新增、删除、修改及基本查询操作
 * <table>
 * <tr>
 * <td>负责人/principal:</td>
 * <td colspan="2">liuzhh</td>
 * <tr>
 * <td>修改记录/revision:</td>
 * <td colspan="2"></td>
 * </tr>
 * <tr>
 * <td>日期:</td>
 * <td>修改人:</td>
 * <td>修改说明:</td>
 * </tr>
 * <tr>
 * <td></td>
 * <td></td>
 * <td></td>
 * </tr>
 * </table>
 * @author liuzhh
 * @version $Id$
 */
public class BaseDAO<B extends BaseEntity> extends HibernateDaoSupport
        implements IBaseDAO<B>
{
    private static final String FROM_ = " from ";

    /**
     * 获取实体类
     * @param b
     * @return
     */
    public String getEntityName()
    {
        return new BaseEntity().getClass().getName();
    }

    /**
     * 用于数据保存
     * @param baseEntity
     */
    public void save(B baseEntity)
    {
        if (baseEntity != null)
        {
            getHibernateTemplate().save(baseEntity);
            //getHibernateTemplate().saveOrUpdate(baseEntity);
        }
    }

    public void merge(B baseEntity)
    {
        if (baseEntity != null)
        {
            getHibernateTemplate().merge(baseEntity);
        }
    }
    /**
     * 用于删除实体数据
     * @param baseEntity
     */
    public void delete(B baseEntity)
    {
//        getHibernateTemplate().delete(baseEntity);

        final String fEntityName = getEntityName();
        final int id=baseEntity.getId();
        getHibernateTemplate().execute(new HibernateCallback()
        {
            public Object doInHibernate(Session session)
                    throws HibernateException
            {
                String hql = "update " + fEntityName + " b set b.end=sysdate where b.id" 
                + " = " + id ;
                
                session.createQuery(hql).executeUpdate();
                return true;
            }
        });
    }

    /**
     * 根据ID进行删除
     * @param id
     */
    public void deleteById(String id)
    {
        delete(getEntityName(), "id", id);
    }

    public void removeById(Object id)
    {
    	String hql="delete from "+getEntityName()+" where id=?";
        getHibernateTemplate().bulkUpdate(hql, id);
    }
    /**
     * 实现根据实体值删除对应实体对象
     * @param entity
     * @param a
     */
    public final void batchDelete(Object entity, String a)
    {
        String hql = "delete from " + entity.getClass().getName();
        getSession().createQuery(hql).executeUpdate();
    }

    /**
     * 根据参数和参数值直接删除对应条件数据
     * @param entity
     * @param param
     * @param paramValue
     */
    public final void delete(Object entity, String param, String paramValue)
    {
        final String fParam = param;
        final String fParamValue = paramValue;
        final String fEntityName = getEntityName();

        getHibernateTemplate().execute(new HibernateCallback()
        {
            public Object doInHibernate(Session session)
                    throws HibernateException
            {
//                String hql = "delete from " + fEntityName + " where " + fParam
//                        + " = '" + fParamValue + "'";
                String hql = "update " + fEntityName + " b set b.end=sysdate where b." + fParam
                + " = '" + fParamValue + "'";
                
                session.createQuery(hql).executeUpdate();
                return true;
            }
        });
    }

    /**
     * 根据实体名称和参数、参数值进行删除操作
     * @param entityName
     * @param param
     * @param paramValue
     */
    public final void delete(String entityName, String param, String paramValue)
    {
        final String fParam = param;
        final String fParamValue = paramValue;
        final String fEntityName = entityName;

        getHibernateTemplate().execute(new HibernateCallback()
        {
            public Object doInHibernate(Session session)
                    throws HibernateException
            {
//                String hql = "delete from " + fEntityName + " where " + fParam
//                        + " = '" + fParamValue + "'";
                String hql = "update " + fEntityName + " b set b.end=sysdate where b." + fParam
                + " = '" + fParamValue + "'";
                session.createQuery(hql).executeUpdate();
                return true;
            }
        });
    }

    /**
     * 根据传入的参数和参数值的集合删除数据
     * @param entity
     * @param param
     * @param paramValues
     */
    public void delete(Object entity, String param, String[] paramValues)
    {
        final String fParam = param;
        final String[] fParamValues = paramValues;
        final String fEntityName = getEntityName();

        getHibernateTemplate().execute(new HibernateCallback()
        {
            public Object doInHibernate(Session session)
                    throws HibernateException
            {
                if (fParamValues != null && fParamValues.length > 0)
                {
                    for (String value : fParamValues)
                    {
//                        String hql = "delete from " + fEntityName + " where "
//                                + fParam + " = '" + value + "'";

                        String hql = "update " + fEntityName + "b set b.end=sysdate where b." + fParam
                        + " = '" + value + "'";
                        
                        session.createQuery(hql).executeUpdate();
                    }
                }
                return true;
            }
        });
    }
    
    /**
     * 执行逻辑删除
     * @param entityName
     * @param param
     * @param paramValue
     */
    public void remove(String entityName)
    {
        final String fEntityName = entityName;
        getHibernateTemplate().execute(new HibernateCallback()
        {
            public Object doInHibernate(Session session)
                    throws HibernateException
            {
                String hql = "update " + fEntityName + " set end=sysdate ";
                session.createQuery(hql).executeUpdate();
                return true;
            }
        });
    }
    
    /**
     * 根据唯一键值获取实体
     * @param id
     * @return
     */
    @SuppressWarnings("unchecked")
    public B findById(Integer id)
    {
        return (B) getHibernateTemplate().get(getEntityName(), id);
    }

    /**
     * 修改实体数据
     * @param baseEntity
     */
    public void update(B baseEntity)
    {
        getHibernateTemplate().update(baseEntity);
    }

    /**
     * 获取所有同类实体数据
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<B> findAll()
    {
        return getHibernateTemplate().executeFind(
                new HibernateCallback()
                {
                    public List doInHibernate(Session session)
                            throws HibernateException
                    {
                        Criteria criteria = session
                                .createCriteria(getEntityName());
                        // 设置查询条件,查询有效数据
                        Criterion criterion = Restrictions.gt("end", getCurrSysdate());
                        criteria.add(criterion);
                        return criteria.list();
                    }
                });
    }
    
    /**
     * 
     * 取一定数据
     * @param num
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<B> findAll(int num,final String orderParam)
    {
        final int endRow=num;
        return getHibernateTemplate().executeFind(
                new HibernateCallback()
                {
                    public List doInHibernate(Session session)
                            throws HibernateException
                    {
                        Criteria criteria = session
                                .createCriteria(getEntityName());
                        // 设置查询条件
                        Criterion criterion = Restrictions.gt("end", getCurrSysdate());

                        criteria.add(criterion);
                        // 设置翻页数据
                        criteria.setFirstResult(0);
                        criteria.setMaxResults(endRow);
                        
                        //按创建时间
                        criteria.addOrder(Order.desc(orderParam));
                        
                        return criteria.list();
                    }
                });
    } 
    
    /**
     * 按查询条件获取总数
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<B> findBy(Criterion cond)
    {
        final Criterion conds=cond;
        return getHibernateTemplate().executeFind(
                new HibernateCallback()
                {
                    public List doInHibernate(Session session)
                            throws HibernateException
                    {
                        Criteria criteria = session
                                .createCriteria(getEntityName());
                        // 设置查询条件,查询有效数据
                        Criterion criterion = Restrictions.gt("end", getCurrSysdate());
                        if (conds!=null) criterion=Restrictions.and(criterion, conds);
                        criteria.add(criterion);

                        //按创建时间
                        criteria.addOrder(Order.desc("begin"));
                        
                        return criteria.list();
                    }
                });
    }
    
    /**
     * 
     * 按查询条件获取总数并按照排序字段进行排序
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<B> findByAndOrder(Criterion cond,String orderParam,String strOrder)
    {
        final Criterion conds=cond;
        final String ordParam=orderParam;
        final String strOrd=strOrder;
        return getHibernateTemplate().executeFind(
                new HibernateCallback()
                {
                    public List doInHibernate(Session session)
                            throws HibernateException
                    {
                        Criteria criteria = session
                                .createCriteria(getEntityName());
                        // 设置查询条件,查询有效数据
                        Criterion criterion = Restrictions.gt("end", getCurrSysdate());
                        if (conds!=null) criterion=Restrictions.and(criterion, conds);
                        criteria.add(criterion);

                        //按创建时间
                        if (strOrd.equalsIgnoreCase("DESC")){
                            criteria.addOrder(Order.desc(ordParam));
                        }else if (strOrd.equalsIgnoreCase("ASC")){
                            criteria.addOrder(Order.asc(ordParam));                            
                        }
                        
                        return criteria.list();
                    }
                });
    } 
    /**
     * 获取所有同类实体数据并实现翻页
     * @param currPage
     * @param pageSize
     * @return
     */
    @SuppressWarnings("unchecked")
    public PageControl findAllByPage(int currPage, int pageSize)
    {
      
        PageControl pageControl=new PageControl(findAll().size(),currPage,pageSize);

        final int startRow = pageControl.getStart();
        final int endRow=pageControl.getPageSize();
        
        List<B> results = getHibernateTemplate().executeFind(
                new HibernateCallback()
                {
                    public List doInHibernate(Session session)
                            throws HibernateException
                    {

                        Criteria criteria = session
                                .createCriteria(getEntityName());
                        // 设置查询条件
                        Criterion criterion = Restrictions.gt("end", getCurrSysdate());

                        criteria.add(criterion);
                        // 设置翻页数据
                        criteria.setFirstResult(startRow);
                        criteria.setMaxResults(endRow);

                        //按创建时间
                        criteria.addOrder(Order.desc("begin"));
                        
                        return criteria.list();
                    }
                });
        ;
        
        return new PageControl(results, startRow, pageSize, currPage,
                pageControl.getTotalPage(), pageControl.getTotal());
    }
    
    /**
     * 按条件查询翻页
     * @param cond
     * @param currPage
     * @param pageSize
     * @return
     */
    @SuppressWarnings("unchecked")
    public PageControl findByPage(Criterion cond,int currPage, int pageSize)
    {
      
        PageControl pageControl=new PageControl(findBy(cond).size(),currPage,pageSize);

        final int startRow = pageControl.getStart();
        final int endRow=pageControl.getPageSize();
        final Criterion conds=cond;
        
        List<B> results = getHibernateTemplate().executeFind(
                new HibernateCallback()
                {
                    public List doInHibernate(Session session)
                            throws HibernateException
                    {
                        Criteria criteria = session
                                .createCriteria(getEntityName());
                        // 设置查询条件
                        Criterion criterion = Restrictions.gt("end", getCurrSysdate ());
                        if (conds!=null) 
                        	criterion=Restrictions.and(criterion, conds);
                        criteria.add(criterion);
                        // 设置翻页数据
                        criteria.setFirstResult(startRow);
                        criteria.setMaxResults(endRow);

                        //按创建时间
                        criteria.addOrder(Order.desc("begin"));
                        
                        return criteria.list();
                    }
                });
        ;
        
        return new PageControl(results, startRow, pageSize, currPage,
                pageControl.getTotalPage(), pageControl.getTotal());
    }
    
    public PageControl findByPage(Expression exp,int currPage, int pageSize){
        return new PageControl();
    }
    
    /**
     * 获取数据库当前时间
     * @param sequenceName
     * @return
     */
    @SuppressWarnings("deprecation")
    public Date getCurrSysdate()
    {
        String sql = "select sysdate from dual";

        Date result = new Date();
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        Session session = null;
        try
        {
            session = getSession();
            conn = session.connection();
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
            while (rs.next())
            {
                Date date = rs.getDate(1);
                Time time=rs.getTime(1);
                result=new Date(date.getYear(),date.getMonth(),date.getDate(),time.getHours(),time.getMinutes(),time.getSeconds());
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            if (session != null)
            {
                releaseSession(session);
            }
        }
  
        return result;
    }

    /**
     * 获取数据库中seq的nextval
     * @param sequenceName
     * @return
     */
    @SuppressWarnings("deprecation")
    public String getNextval(String seqName)
    {
        String sql = "select sysdate,lpad("+seqName+".nextval,4,'0') from dual";    //select sysdate,lpad(seq_req_num.nextval,4,'0') from dual

        String str= "";
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        Session session = null;
        try
        {
            session = getSession();
            conn = session.connection();
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
            if (rs.next())
            {
                Date date = rs.getDate(1);
                String next = rs.getString(2);
                Time time=rs.getTime(1);
                
                Date today=new Date();
                SimpleDateFormat f=new SimpleDateFormat("yyMMdd");
                str=f.format(today)+next;
                System.out.println(str);

                //str= date.getYear()+date.getMonth()+date.getDate()+next;
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            if (session != null)
            {
                releaseSession(session);
            }
        }
  
        return str;
    }
}
